/**
 * Proxy代理模式是一种结构型设计模式，主要解决的问题是：
 *    在直接访问对象时带来的问题，比如说：要访问的对象在远程的机器上。
 * 
 * 代理模式分为静态代理和动态代理，来一个俗的例子说明，你有两个同学B和C，B是男的，C是女的，
 * 你晚上想给女同学C打电话咨询点事，但是你女友醋意大发，坚决不让（在程序上表现为因为各种原因不能直接调用目标类），
 * 所以，你只能通过你的男同学B和C通话，然后把让B把反馈的结果告诉你。
 * @author MIAO
 * Created on 2011-10-11
 * For more information, please visit:ismiao.com
 */
package com.ismiao.designPattern.Proxy;

public class ProxyDesc {
/**
 * 一、Proxy模式定义:
 *    为其他对象提供一种代理以控制这个对象的访问。
 *    
 * 二、模式解说
 *    Proxy代理模式是一种结构型设计模式。
 *    主要解决的问题是：在直接访问对象时带来的问题，
 *       比如说：要访问的对象在远程的机器上。
 *       在面向对象系统中，有些对象由于某些原因（比如对象创建开销很大，
 *       或者某些操作需要安全控制，或者需要进程外的访问），直接访问会给使用者或者系统结构带来
 *       很多麻烦，我们可以在访问此对象时加上一个对此对象的访问层,这个访问层也叫代理。
 *       Proxy模式是最常见的模式，在我们生活中处处可见，例如我们买火车票不一定非要到火车站去买，可以到一些火车票的代售点去买。
 *       寄信不一定是自己去寄，可以把信委托给邮局，由邮局把信送到目的地，现实生活中还有很多这样的例子，就不一一列举了。
 *       
 * 三、结构图
 *    Proxy模式结构图如下:
 *    
 * 四、一个例子
 *    举一个比较俗的例子，一个男孩boy喜欢上了一个女孩girl，男孩一直想认识女孩，
 *    直接去和女孩打招呼吧，又觉得不好意思（这个男孩比较害羞）。于是男孩想出了一个办法，
 *    委托女孩的室友Proxy去帮他搞定这件事（获得一些关于女孩的信息，如有没有BF等,这就叫知己知彼，才能百战不殆）。
 *    下面给出这个例子的程序实现：
    interface GirlInfo{
    	public void hasBoyFriend();
    }
    class Girl implements GirlInfo{
    	public void hasBoyFriend(){
    		System.out.println("还没有男朋友");
    	}
    }
    class Proxy implements GirlInfo{
		private GirlInfo _girl;
		public Proxy(GirlInfo girl){
			_girl=girl;
		}
		public void hasBoyFriend(){
			_girl.hasBoyFriend();
		}
	   }
    public class ProxyClient {
		public static void main(String[] args) {
		　 GirlInfo girl=new Girl();
		　 Proxy proxy=new Proxy(girl);
		　 proxy.hasBoyFriend();
	    }
    }
	从这个例子我们可以看出，Proxy模式是不是和Adapter模式差不多，都是调用一个已有对象的方法来完成功能。
	但是他们之间还是有区别的，那就是Proxy模式的目标类必须要实现某个接口，代理类没有必要实现该接口，模式是死的，它的实现是活的，如果一味的相信某些书上的实现，学习模式也就失去了意义。
	有的书上称这种实现为静态代理，之所以这样是为了区别于Proxy模式在jdk中的另一种实现,jdk中的实现称为动态代理。
	下面用jdk中的方法给出这个例子的实现。代码如下:
		import java.lang.reflect.InvocationHandler;
		import java.lang.reflect.Method;
		import java.lang.reflect.Proxy;
		interface GirlInfo{
		public void hasBoyFriend();
		}
		class Girl implements GirlInfo{
           	public void hasBoyFriend(){
		　      	System.out.println("还没有男朋友");
			}
		}
		class GirlProxy implements InvocationHandler{
			private Object delegate;
			public Object bind(Object delegate){
		　		this.delegate=delegate;
		　		return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(),this);
			}
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		　		method.invoke(delegate, args);
		　		return null;
			}
		}
		public class ProxyClient {
			public static void main(String[] args) {
		　	GirlProxy girlProxy=new GirlProxy();
		　	GirlInfo girl=(GirlInfo)girlProxy.bind(new Girl());
		　	girl.hasBoyFriend();
			}
		}
		五、适用性
		　　1）假如有一个外部组件包，不允许实现其接口，则就只能使用其动态代理了。
		　　2）直接访问一个对象很困难，或者说不能访问，此时只能是找个代理去访问，然后把结果反馈给自己。
		六、优缺点
		　　1)优点: 向客户端隐藏了访问某个对象的细节及复杂性；可以动态地调用一个对象中的方法，且无需实现固定的接口。
		　　2)缺点：暂时没发现
		
		在我看来，proxy主要用来代理某个类的实现，便于进行访问控制；
		        adapter主要是缺省实现某个接口，便于进行函数覆写； 
                   但是看了两个示例代码后，好像要用一个已有类去实现他们继承的抽象类或者借口才能算是符合这两种模式。
                   感觉自己理解的不够透彻，继续请教！！
*/
}
